﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BaseStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            //var s1 = "123"+"456";
            //Console.WriteLine(s1);

            //位运算符


            /*
             *运算符	说 明
                 &	    按位与。两个运算数都为 1，则整个表达式为 1，否则为 0;也可以对布尔型的值进行比较，相当于“与”运算，但不是短路运算
                 |	    按位或。两个运算数都为 0，则整个表达式为 0，否则为 1;也可以对布尔型的值进行比较，相当于“或”运算，但不是短路运算
                 ~	    按位非。当被运算的值为 1 时，运算结果为 0;当被运算的值为 0 时，运算结果为 1。该操作符不能用于布尔型。对正整数取反，则在原来的数上加 1，然后取负数；对负整数取反，则在原来的数上加 1，然后取绝对值
                 ^	    按位异或。只有运算的两位不同结果才为 1，否则为 0
                 <<	    左移。把运算符左边的操作数向左移动运算符右边指定的位数，右边因移动空出的部分 补 0
                 >>	    有符号右移。把运算符左边的操作数向右移动运算符右边指定的位数。如果是正值，左侧因移动空出的部分补 0;如果是负值，左侧因移动空出的部分补 1
                 >>>    无符号右移。和 >> 的移动方式一样，只是不管正负，因移动空出的部分都补 0
             *
             */
            //var i1 = 10;
            //Console.WriteLine(i1<<1);//10+10
            //Console.WriteLine(3<<1);//3+3
            //Console.WriteLine(i1 << 2);//10+10+10+10
            //Console.WriteLine(3 << 2);//3+3+3+3
            //Console.WriteLine(i1 << 3);//10+10+10+10+10+10+10+10
            //Console.WriteLine(3 << 3);//3+3+3+3+3+3+3+3
            //Console.WriteLine(1 << 3);//1+1+1+1+1+1+1+1
            //Console.WriteLine(1 << 5);32个1相加

            //Console.WriteLine(i1 >> 2);
            //Console.WriteLine(3 >> 1);
            //Console.WriteLine(1 >> 6);
            //###############################goto使用############################################//
            //int count = 0;
            //login:
            //Console.WriteLine("请输入用户名");
            //string username = Console.ReadLine();
            //Console.WriteLine("请输入密码");
            //string userpwd = Console.ReadLine();
            //if (username == "aaa" && userpwd == "123")
            //{
            //    Console.WriteLine("登录成功");
            //}
            //else
            //{
            //    count++;
            //    if (count > 3)
            //    {
            //        Console.WriteLine("用户名或密码错误次数过多！退出！");
            //    }
            //    else
            //    {
            //        Console.WriteLine("用户名或密码错误");
            //        goto login;//返回login标签处重新输入用户名密码
            //    }
            //}
            //var mclass = new MyClass();

            //var rands=new Random(1212);
            //student stu = new student {Age = 101, Name = "张三"};
            //stu.ShowInfo();
            //People man = new Man
            //{
            //    Name = "张三"
            //};
            //man.Speek("汉语");
            //IPeople woman = new Woman
            //{
            //    name = "小红"
            //};
            //woman.Speek("英语");


            //DriveInfo driveInfo = new DriveInfo("C"); 
            //Console.WriteLine("驱动器的名称：" + driveInfo.Name);
            //Console.WriteLine("驱动器类型：" + driveInfo.DriveType);
            //Console.WriteLine("驱动器的文件格式：" + driveInfo.DriveFormat);
            //Console.WriteLine("驱动器中可用空间大小：" + driveInfo.TotalFreeSpace);
            //Console.WriteLine("驱动器总大小：" + driveInfo.TotalSize);

            //var arr=Process.GetProcesses();
            //arr.ToList().ForEach(x =>
            //{
            //    Console.WriteLine(x.ProcessName);
            //});
            //Console.ReadLine();

            /**
             *
             *
             *
             集合与数组比较类似，都用于存放一组值，但集合中提供了特定的方法能直接操作集合中的数据，并提供了不同的集合类来实现特定的功能。
            集合简单的说就是数组的升级版。他可以动态的对集合的长度（也就是集合内最大元素的个数）进行定义和维护！
            所有集合类或与集合相关的接口命名空间都是 System.Collection，在该命名空间中提供的常用接口如下表所示。

            接口名称	                作用
            IEnumerable	                用于迭代集合中的项，该接口是一种声明式的接口
            IEnumerator	                用于迭代集合中的项，该接口是一种实现式的接口
            ICollection	                .NET 提供的标准集合接口，所有的集合类都会直接或间接地实现这个接口
            IList	                    继承自 IEnumerable 和 ICollection 接口，用于提供集合的项列表，并允许访问、查找集合中的项
            IDictionary	                继承自 IEnumerable 和 ICollection 接口，与 IList 接口提供的功能类似，但集 合中的项是以键值对的形式存取的
            IDictionaryEnumerator	    用于迭代 IDictionary 接口类型的集合
            针对上表中的接口有一些常用的接口实现类，如下表所示。

            类名称	     实现接口	                                                特点
            ArrayList	ICollection、IList、IEnumerable、ICloneable	                集合中元素的个数是可变的，提供添加、删除等方法
            Queue	    ICollection、IEnumerable、ICloneable	                    集合实现了先进先出的机制，即元素将在集合的尾部添加、在集合的头部移除
            Stack	    ICollection、IEnumerable、ICloneable	                    集合实现了先进后出的机制，即元素将在集合的尾部添加、在集合的尾部移除
            Hashtable	IDictionary、ICollection、IEnumerable、ICloneable 等接口	集合中的元素是以键值对的形式存放的，是 DictionaryEntry 类型的
            SortedList	IDictionary、ICollection、IEnumerable、ICloneable 等接口	与 Hashtable 集合类似，集合中的元素以键值对的形式存放，不同的是该集合会按照 key 值自动对集合中的元素排序
             *
             *
             */

            //dynamic id = 12;
            //Console.WriteLine(id.GetType()==typeof(int));
            //Console.WriteLine(id is Guid);

            //var mo = new PeopleAdd(); 
            //Console.WriteLine(mo.GetType().GetMembers().Where(x=>x.Name=="Id").Count());
            //bool ac = true;
            //Console.WriteLine(ac.ToString().ToLower());

            var ids = new CommonIdentity();
            var arr = new List<long>();            
            for (int i = 0; i < 39; i++)
            {
                var nu = ids.NextNumber();
               Console.WriteLine(nu);
                arr.Add(nu);
            }
            Console.WriteLine(arr.Distinct().Count());
            Console.ReadLine();
        }
    }

    class MyClass
    {
        ~MyClass()
        {
            Console.WriteLine("调用了析构函数");
        }
    }

    public struct student
    {
        private string name;
        private int age;

        public string Name
        {
            get => name;
            set => name = value;
        }
        public int Age
        {
            get => age;
            set
            {
                if (value > 100 || value < 0)
                    age = 0;
                else
                    age = value;
            }
        }

        public void ShowInfo()
        {
            Console.WriteLine($"姓名：{name} 年龄：{age}");
        }
    }

    public abstract class People
    {
        public abstract string Name { get; set; }
        public abstract void Speek(string langs);
    }

    public interface IPeople
    {
        string name { get; set; }
        void Speek(string langs);
    }

    public class Man : People
    {
        public override string Name { get; set; }
        public override void Speek(string langs)
        {
            Console.WriteLine($"{Name} 说 {langs}");
        }
    }
    public class Woman : IPeople
    {
        public string name { get; set; }

        public void Speek(string langs)
        {
            Console.WriteLine($"{name} 说 {langs}");
        }
    }

    // 构造类不能继承抽象类
    //public struct Boy : People
    //{

    //}

    public class PeopleAdd
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class CommonIdentity
    {
        private Random random=new Random(Guid.NewGuid().GetHashCode());
        public string NextId()
        { 
            var randomNumber = GetRandom();
            var nowTimes = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssffff"));
            var nextNumber = nowTimes + randomNumber;
            return $"{nextNumber}";
        }

        public long NextNumber()
        { 
            var randomNumber = GetRandom();
            var nowTimes = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssffff"));
            return nowTimes + randomNumber;
        }

        /// <summary>
        /// 生成随机数
        /// </summary>
        private long GetRandom()
        {
            byte[] randomBytes = new byte[8];
            System.Security.Cryptography.RNGCryptoServiceProvider rngServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rngServiceProvider.GetBytes(randomBytes);
            //var sub = GetNextRandom();
            //var nexts = BitConverter.ToInt64(Guid.NewGuid().ToByteArray(),0)/ sub/ sub/sub;
            var nextNums = GetNextRandom();
            var nums =  (int)(Math.Abs(BitConverter.ToInt64(randomBytes, 0)) / Int64.MaxValue * (100000 + 1));
            if (nextNums % 2 == 0) return nums + nextNums;
            return Math.Abs(nums- nextNums);
            //return Math.Abs(nexts + nums) - nextNums;
        }


        private  int GetNextRandom()
        {
            string nowGuid = Guid.NewGuid().ToString();
            int seed = DateTime.Now.Millisecond+ random.Next(1000, 99999);
            for (int i = 0; i < nowGuid.Length; i++)
            {
                switch (nowGuid[i])
                {
                    case 'a':
                        seed = seed + 1;
                        break;
                    case 'b':
                        seed = seed + 3;
                        break;
                    case 'c':
                        seed = seed + 5;
                        break;
                    case 'd':
                        seed = seed + 7;
                        break;
                    case 'e':
                        seed = seed + 11;
                        break;
                    case 'f':
                        seed = seed + 13;
                        break;
                    case 'g':
                        seed = seed + 17;
                        break;
                    case 'h':
                        seed = seed + 19;
                        break;
                    case 'i':
                        seed = seed - 31;
                        break;
                    case 'j':
                        seed = seed + 37;
                        break;
                    case 'k':
                        seed = seed + 53;
                        break;
                    case 'l':
                        seed = seed - 57;
                        break;
                    case 'm':
                        seed = seed + 61;
                        break;
                    case 'n':
                        seed = seed + 73;
                        break;
                    case 'o':
                        seed = seed + 2;
                        break;
                    case 'p':
                        seed = seed - 33;
                        break;
                    case 'q':
                        seed = seed - 91;
                        break;
                    case 'r':
                        seed = seed - 10;
                        break;
                    case 's':
                        seed = seed + 23;
                        break;
                    case 't':
                        seed = seed - 29;
                        break;
                    case 'u':
                        seed = seed + 15;
                        break;
                    case 'v':
                        seed = seed + 87;
                        break;
                    case 'w':
                        seed = seed - 24;
                        break;
                    case 'x':
                        seed = seed + 8;
                        break;
                    case 'y':
                        seed = seed - 71;
                        break;
                    case 'z':
                        seed = seed + 39;
                        break;
                    default:
                        seed = seed - 9;
                        break;
                }
            }
            return Math.Abs(seed) ;
        }
    }
}
